﻿using System;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Navigation;

namespace SLSearchNavSync.HelperClasses
{
    /// <summary>
    /// Contains methods for managing site search settings
    /// </summary>
    internal static class SearchSettingsHelper
    {
        /// <summary>
        /// Synchronizes the search navigation settings from a search center to a specific site
        /// </summary>
        /// <param name="searchCenterWeb">SPWeb object for the search center</param>
        /// <param name="targetWeb">SPWeb object for the target site</param>
        /// <param name="addThisSite">Flag for adding in the contextual search this site</param>
        /// <param name="thisSiteIsFirst">Flag for adding contextual search this site first (otherwise it's last)</param>
        internal static void SyncSearchNavigation(SPWeb searchCenterWeb, SPWeb targetWeb, bool addThisSite, bool thisSiteIsFirst)
        {
            try
            {
                //return if the target web is a search center
                if (targetWeb.WebTemplate.StartsWith("SRCHCEN")) return;

                //delete all links in target
                var targetSearchNav = targetWeb.Navigation.SearchNav;
                for (var i = targetSearchNav.Count - 1; i >= 0; i--)
                {
                    targetSearchNav[i].Delete();
                }
                //set the search center url
                targetWeb.AllProperties["SRCH_ENH_FTR_URL_WEB"] = searchCenterWeb.Url + "/Pages/";

                //now add all the search center navigation items
                var searchCenterNav = searchCenterWeb.Navigation.SearchNav;
                for (var i = searchCenterNav.Count - 1; i >= 0; i--)
                {
                    var searchNode = searchCenterNav[i];

                    //set the search results page url (if in the same site collection, leave relative)
                    var url = searchCenterWeb.Site.ID == targetWeb.Site.ID
                              ? searchNode.Url
                              : searchCenterWeb.Site.MakeFullUrl(searchNode.Url);
                    var node = new SPNavigationNode(searchNode.Title, url, true);
                    targetSearchNav.AddAsFirst(node);
                }

                //add contextual search "this site" back
                if (addThisSite)
                {
                    var thisSiteSearchResults = targetWeb.Url + "/_layouts/15/osssearchresults.aspx?u=" +
                                                HttpUtility.UrlEncode(targetWeb.Url);
                    var thisSitenode = new SPNavigationNode("This Site", thisSiteSearchResults, false);
                    if (thisSiteIsFirst)
                    {
                        targetSearchNav.AddAsFirst(thisSitenode);
                    }
                    else
                    {
                        targetSearchNav.AddAsLast(thisSitenode);
                    }
                }

                targetWeb.Update();
            }
            catch (Exception ex)
            {
                UlsHelper.WriteUlsEntry(ex, TraceSeverity.Unexpected, String.Empty, Definitions.UlsCategory);
            }
        }

        /// <summary>
        /// Determines if the search navigation settings have been updated
        /// </summary>
        /// <param name="searchCenterWeb">SPWeb object for the search center</param>
        /// <param name="lastRanTime">The last time the changes were checked</param>
        /// <param name="numSearchNodes">The previous number of navigation nodes</param>
        /// <returns></returns>
        internal static bool HasSearchNavigationChanges(SPWeb searchCenterWeb, DateTime lastRanTime, int numSearchNodes)
        {
            var retVal = false;
            try
            {
                var searchCenterNav = searchCenterWeb.Navigation.SearchNav;
                if (searchCenterNav.Count != numSearchNodes)
                {
                    retVal = true;
                }
                else
                {
                    for (var i = searchCenterNav.Count - 1; i >= 0; i--)
                    {
                        if (searchCenterNav[i].LastModified.CompareTo(lastRanTime.ToUniversalTime()) >= 0)
                        {
                            retVal = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                UlsHelper.WriteUlsEntry(ex, TraceSeverity.Unexpected, String.Empty, Definitions.UlsCategory);
            }

            return retVal;
        }
    }
}
